package com.zbj.homemade.mybatis;

import com.zbj.homemade.mybatis.conf.Configuration;
import com.zbj.homemade.mybatis.conf.MappedStatement;
import com.zbj.homemade.mybatis.proxy.MapperProxy;

import java.lang.reflect.Array;
import java.lang.reflect.Proxy;
import java.sql.SQLException;
import java.util.List;

/**
 * @program: principle
 * @description:
 * @author: Yinn
 * @create: 2019-01-11 16:46
 **/
public class DefaultSqlSession implements SqlSession {


    private Configuration configuration;

    private Executor executor = new SimpleExecutor();

    public DefaultSqlSession(Configuration configuration) {
        this.configuration = configuration;
    }

    @Override
    public <T> T selectOne(String statement, Object parameter) {

        List<T> result = this.selectList(statement,parameter);

        if (result == null)
            return null;

        if (result.size() == 1){
            return result.get(0);
        }else if (result.size() == 0){
            return null;
        }

        throw new RuntimeException("太多返回值");
    }

    @Override
    public int insert(String statement, Object parameter) {
        //自己实现就行
        return 0;
    }

    @Override
    public <E> List<E> selectList(String statement, Object parameter) {
        try {
            MappedStatement ms = configuration.getMappedStatement(statement);

            Object[] params;
            if (parameter.getClass().isArray()) {
                params = (Object[])parameter;
            }else {
                params = new Object[]{parameter};
            }

            List<E> result = executor.query(ms, params);

            return result;

        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public int delete(String statement, Object parameter) {
        //自己实现就行
        return 0;
    }

    @Override
    public int update(String statement, Object parameter) {
        //自己实现就行
        return 0;
    }

    @Override
    public <T> T getMapper(Class<T> type) {

        /**
         * 动态代理
         */
        final MapperProxy<T> mapperProxy = new MapperProxy<T>(type, this);

        return (T) Proxy.newProxyInstance(type.getClassLoader(), new Class[] { type }, mapperProxy);
    }

    @Override
    public Configuration getConfiguration() {
        return configuration;
    }
}
